#pragma once

#include "includeBase.h"
#include "../common/BasePclModel.h"

class CorrespondenceGroupingModel : public BasePclModel
{
public:
    CorrespondenceGroupingModel();

public:
    static CorrespondenceGroupingModel& get();

public: // IJsonSerializable
    void fromJson(const QJsonObject& json, QStringList& errorList) override;
    QJsonObject toJson() const override;

public: // Property
    QString modelFile() const { return modelFile_; }
    void setModelFile(const QString& modelFile) { modelFile_ = modelFile; }

    QString sceneFile() const { return sceneFile_; }
    void setSceneFile(const QString& sceneFile) { sceneFile_ = sceneFile; }

    bool showKeypoints() const { return showKeypoints_; }
    void setShowKeypoints(bool showKeypoints)
    {
        showKeypoints_ = showKeypoints;
    }

    bool showCorrespondences() const { return showCorrespondences_; }
    void setShowCorrespondences(bool showCorrespondences)
    {
        showCorrespondences_ = showCorrespondences;
    }

    bool useCloudResolution() const { return useCloudResolution_; }
    void setUseCloudResolution(bool useCloudResolution)
    {
        useCloudResolution_ = useCloudResolution;
    }

    bool useHough() const { return useHough_; }
    void setUseHough(bool useHough) { useHough_ = useHough; }

    float modelSamplingSize() const { return modelSamplingSize_; }
    void setModelSamplingSize(float modelSamplingSize)
    {
        modelSamplingSize_ = modelSamplingSize;
    }

    float sceneSamplingSize() const { return sceneSamplingSize_; }
    void setSceneSamplingSize(float sceneSamplingSize)
    {
        sceneSamplingSize_ = sceneSamplingSize;
    }

    float lrfSupportRadius() const { return lrfSupportRadius_; }
    void setLrfSupportRadius(float lrfSupportRadius)
    {
        lrfSupportRadius_ = lrfSupportRadius;
    }

    float shotDescriptorRadius() const { return shotDescriptorRadius_; }
    void setShotDescriptorRadius(float shotDescriptorRadius)
    {
        this->shotDescriptorRadius_ = shotDescriptorRadius;
    }

    float clusteringBinSize() const { return clusteringBinSize_; }
    void setClusteringBinSize(float clusteringBinSize)
    {
        this->clusteringBinSize_ = clusteringBinSize;
    }

    float clusteringThresh() const { return clusteringThresh_; }
    void setClusteringThresh(float clusteringThresh)
    {
        clusteringThresh_ = clusteringThresh;
    }

private:
    QString modelFile_ = "data/tutorials/correspondence_grouping/milk.pcd";
    QString sceneFile_ = "data/tutorials/correspondence_grouping/"
                         "milk_cartoon_all_small_clorox.pcd";

    // Algorithm params
    bool showKeypoints_ = true;
    bool showCorrespondences_ = true;
    bool useCloudResolution_ = false;
    bool useHough_ = true;
    float modelSamplingSize_ = 0.01f;
    float sceneSamplingSize_ = 0.03f;
    float lrfSupportRadius_ = 0.015f;
    float shotDescriptorRadius_ = 0.02f;
    float clusteringBinSize_ = 0.01f;
    float clusteringThresh_ = 5.0f;
};
